{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# [详解Java的自动装箱与拆箱(autoboxing and unboxing)](https://www.cnblogs.com/wang-yaz/p/8516151.html)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 为什么需要包装类\n",
    "很多人会有疑问，既然Java中为了提高效率，提供了八种基本数据类型，为什么还要提供包装类呢？\n",
    "\n",
    "这个问题，其实前面已经有了答案，因为Java是一种面向对象语言，很多地方都需要使用对象而不是基本数据类型。比如，在集合类中，我们是无法将int 、double等类型放进去的。因为集合的容器要求元素是Object类型。\n",
    "\n",
    "为了让基本类型也具有对象的特征，就出现了包装类型，它相当于将基本类型“包装起来”，使得它具有了对象的性质，并且为其添加了属性和方法，丰富了基本类型的操作。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 自动装箱拆箱 "
   ]
  },
  {
   "attachments": {
    "image.png": {
     "image/png": "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"
    }
   },
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "基本数据类型的自动装箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0开始提供的功能。\n",
    "\n",
    "**装箱就是自动将基本数据类型转换为包装器类型。**  \n",
    "**拆箱就是自动将包装器类型转换为基本数据类型。**\n",
    "\n",
    "装箱拆箱的类型有：\n",
    "![image.png](attachment:image.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "下面两句代码可以看到装箱和拆箱过程："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "1\n"
     ]
    }
   ],
   "source": [
    "Integer integer=1; //装箱\n",
    "int i=integer;     //拆箱\n",
    "\n",
    "// test\n",
    "System.out.println(integer);\n",
    "System.out.println(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对以上代码进行反编译后可以得到以下代码："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "1\n"
     ]
    }
   ],
   "source": [
    "Integer integer=Integer.valueOf(1); \n",
    "int i=integer.intValue();\n",
    "\n",
    "// test\n",
    "System.out.println(integer);\n",
    "System.out.println(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "从上面反编译后的代码可以看出，`int`的自动装箱都是通过`Integer.valueOf()`方法来实现的，`Integer`的自动拆箱都是通过`integer.intValue`来实现的。如果读者感兴趣，可以试着将八种类型都反编译一遍 ，你会发现以下规律：\n",
    "\n",
    "```\n",
    "自动装箱都是通过包装类的valueOf()方法来实现的.自动拆箱都是通过包装类对象的xxxValue()来实现的。\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 哪些地方会自动拆装箱\n",
    "解过原理之后，在来看一下，什么情况下，Java会帮我们进行自动拆装箱。前面提到的变量的初始化和赋值的场景就不介绍了，那是最简单的也最容易理解的。\n",
    "\n",
    "主要来看一下，那些可能被忽略的场景。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 场景一、将基本数据类型放入集合类\n",
    "Java中的集合类只能接收对象类型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "List<Integer> list = new ArrayList<>();\n",
    "for (int i = 1; i < 10; i ++){\n",
    "    list.add(i);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 补充：集合遍历操作的三种方式\n",
    "1. Iterator迭代器方式\n",
    "2. 增强for循环\n",
    "3. 普通for循环"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "6\n",
      "7\n",
      "8\n",
      "9\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "6\n",
      "7\n",
      "8\n",
      "9\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "6\n",
      "7\n",
      "8\n",
      "9\n"
     ]
    }
   ],
   "source": [
    "// 遍历\n",
    "//1.Iterator迭代器方式\n",
    "Iterator iterator = list.iterator();\n",
    "while(iterator.hasNext()){\n",
    "    System.out.println(iterator.next());\n",
    "}\n",
    "\n",
    "//2.增强for循环\n",
    "for(Object obj:list){\n",
    "    System.out.println(obj);\n",
    "}\n",
    "\n",
    "//3.普通for循环\n",
    "for(int i=0;i<list.size();i++){\n",
    "    System.out.println(list.get(i));\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "将上面初始化代码进行反编译，可以得到以下代码："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "List<Integer> list = new ArrayList<>();\n",
    "for (int i = 1; i < 10; i += 2){\n",
    "    list.add(Integer.valueOf(i));\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "以上，我们可以得出结论，当我们把基本数据类型放入集合类中的时候，会进行自动装箱。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 场景二、包装类型和基本类型的大小比较\n",
    "有没有人想过，当我们对Integer对象与基本类型进行大小比较的时候，实际上比较的是什么内容呢？看以下代码："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "等于\n",
      "假\n"
     ]
    }
   ],
   "source": [
    "Integer a=1;\n",
    "System.out.println(a==1?\"等于\":\"不等于\");\n",
    "Boolean bool=false;\n",
    "System.out.println(bool?\"真\":\"假\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对以上代码进行反编译，得到以下代码："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "等于\n",
      "假\n"
     ]
    }
   ],
   "source": [
    "Integer a=1;\n",
    "System.out.println(a.intValue()==1?\"等于\":\"不等于\");\n",
    "Boolean bool=false;\n",
    "System.out.println(bool.booleanValue()?\"真\":\"假\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到，包装类与基本数据类型进行比较运算，是先将包装类进行拆箱成基本数据类型，然后进行比较的。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 场景三、包装类型的运算\n",
    "有没有人想过，当我们对Integer对象进行四则运算的时候，是如何进行的呢？看以下代码："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "30\n"
     ]
    }
   ],
   "source": [
    "Integer i = 10;\n",
    "Integer j = 20;\n",
    " \n",
    "System.out.println(i+j);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "反编译后代码如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "30\n"
     ]
    }
   ],
   "source": [
    "Integer i = Integer.valueOf(10);\n",
    "Integer j = Integer.valueOf(20);\n",
    "System.out.println(i.intValue() + j.intValue());"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们发现，两个包装类型之间的运算，会被自动拆箱成基本类型进行。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 场景四、三目运算符的使用\n",
    "这是很多人不知道的一个场景，看一个简单的三目运算符的代码："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n"
     ]
    }
   ],
   "source": [
    "boolean flag = false;\n",
    "Integer i = 1;\n",
    "int j = 0;\n",
    "int k = flag ? i : j;\n",
    "\n",
    "// test\n",
    "System.out.println(k);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "很多人不知道，其实在int k = flag ? i : j;这一行，会发生自动拆箱。反编译后代码如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "boolean flag = true;\n",
    "Integer i = Integer.valueOf(1);\n",
    "int j = 0;\n",
    "int k = flag ? i.intValue() : j;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这其实是三目运算符的语法规范：当第二，第三位操作数分别为基本类型和对象时，其中的对象就会拆箱为基本类型进行操作。\n",
    "\n",
    "因为例子中，flag ? i : j;片段中，第二段的i是一个包装类型的对象，而第三段的j是一个基本类型，所以会对包装类进行自动拆箱。如果这个时候i的值为null，那么久会发生NPE。（[自动拆箱导致空指针异常](https://mp.weixin.qq.com/s?__biz=MzI3NzE0NjcwMg==&mid=2650121204&idx=1&sn=3083f0bff6fac7c208037a90dfcce07d&chksm=f36bbed5c41c37c37284b45f7d1f52440a29377b84cbbde9796d648220665458ed638ff6d996&scene=21#wechat_redirect)）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 补充：NPE(Null Pointer Exception)空指针异常"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "ename": "EvalException",
     "evalue": "null",
     "output_type": "error",
     "traceback": [
      "\u001b[1m\u001b[31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1m\u001b[31mjava.lang.NullPointerException: null\u001b[0m",
      "\u001b[1m\u001b[31m\tat .(#61:1)\u001b[0m"
     ]
    }
   ],
   "source": [
    "Map<String, Boolean> map = new HashMap<>();\n",
    "Boolean b = map != null ? map.get(\"test\") : false;\n",
    "System.out.println(b);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "以上这段代码，是我们在不注意的情况下有可能经常会写的一类代码（在很多时候我们都爱使用三目运算符）。\n",
    "\n",
    "一般情况下，我们会认为以上代码Boolean b的最终得到的值应该是null。因为map.get(\"test\")的值是null，而b又是一个对象，所以得到结果会是null。\n",
    "\n",
    "但是，以上代码会抛出NPE：\n",
    "`java.lang.NullPointerException: null`\n",
    "\n",
    "首先可以明确的是，既然报了空指针，那么一定是有些地方调用了一个null的对象的某些方法。在这短短的两行代码中，看上去只有一处方法调用`map.get(\"test\")`，但是我们也都是知道，map已经事先初始化过了，不会是Null，那么到底是哪里有空指针呢。\n",
    "\n",
    "我们接下来反编译一下该代码。看看我们写的代码在经过编译器处理之后变成了什么样。反编译后代码如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "ename": "EvalException",
     "evalue": "null",
     "output_type": "error",
     "traceback": [
      "\u001b[1m\u001b[31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1m\u001b[31mjava.lang.NullPointerException: null\u001b[0m",
      "\u001b[1m\u001b[31m\tat .(#61:1)\u001b[0m"
     ]
    }
   ],
   "source": [
    "Map map = new HashMap();\n",
    "Boolean b = Boolean.valueOf(map == null ? false : ((Boolean)map.get(\"test\")).booleanValue());\n",
    "System.out.println(b);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "看完这段反编译之后的代码之后，经过分析我们大概可以知道问题出在哪里。((Boolean)hashmap.get(\"test\")).booleanValue() 的执行过程及结果如下：\n",
    "```java\n",
    "hashmap.get(\"test\")->null;\n",
    "(Boolean)null->null;\n",
    "null.booleanValue()->报错\n",
    "```\n",
    "好，问题终于定位到了。很明显，上面源代码中的map.get(\"test\")在被编译成了\n",
    "(Boolean)map.get(\"test\").booleanValue()，这是一种自动拆箱的操作。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 原理分析\n",
    "通过查看反编译之后的代码，我们准确的定位到了问题，分析之后我们可以得出这样的结论：NPE的原因应该是三目运算符和自动拆箱导致了空指针异常。\n",
    "\n",
    "那么，这段代码为什么会自动拆箱呢？这其实是三目运算符的语法规范。参见jls-15.25，摘要如下：\n",
    "```\n",
    "If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression.\n",
    "\n",
    "If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T.\n",
    "\n",
    "If one of the second and third operands is of the null type and the type of the other is a reference type, then the type of the conditional expression is that reference type.\n",
    "```\n",
    "所以，结果就是：由于使用了三目运算符，并且第二、第三位操作数分别是基本类型和对象。所以对对象进行拆箱操作，由于该对象为null，所以在拆箱过程中调用null.booleanValue()的时候就报了NPE。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 问题解决"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "null\n",
      "true\n"
     ]
    }
   ],
   "source": [
    "Map<String,Boolean> map =  new HashMap<String, Boolean>();\n",
    "Boolean b = (map!=null ? map.get(\"test\") : Boolean.FALSE);\n",
    "System.out.println(b);\n",
    "\n",
    "map.put(\"test\",true);\n",
    "Boolean b = (map!=null ? map.get(\"test\") : Boolean.FALSE);\n",
    "System.out.println(b);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "就是保证了三目运算符的第二第三位操作数都为对象类型。这样就不会发生自动拆箱操作，以上代码得到的b的结果为null。\n",
    "\n",
    "PS：本文中的示例，只是为了更加方便读者理解三目运算符会导致自动拆箱现象，可能在代码中并不会直接这样使用。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 场景五、函数参数与返回值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "//自动拆箱\n",
    "public int getNum1(Integer num) {\n",
    "    return num;\n",
    "}\n",
    "//自动装箱\n",
    "public Integer getNum2(int num) {\n",
    "    return num;\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 自动拆装箱与缓存\n",
    "Java SE的自动拆装箱还提供了一个和缓存有关的功能"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "integer1 == integer2\n",
      "integer3 != integer4\n",
      "integer5 == integer6\n"
     ]
    }
   ],
   "source": [
    "Integer integer1 = 3;\n",
    "Integer integer2 = 3;\n",
    "\n",
    "if (integer1 == integer2)\n",
    "    System.out.println(\"integer1 == integer2\");\n",
    "else\n",
    "    System.out.println(\"integer1 != integer2\");\n",
    "\n",
    "Integer integer3 = 128;\n",
    "Integer integer4 = 128;\n",
    "\n",
    "if (integer3 == integer4)\n",
    "    System.out.println(\"integer3 == integer4\");\n",
    "else\n",
    "    System.out.println(\"integer3 != integer4\");\n",
    "    \n",
    "Integer integer5 = 127;\n",
    "Integer integer6 = 127;\n",
    "\n",
    "if (integer5 == integer6)\n",
    "    System.out.println(\"integer5 == integer6\");\n",
    "else\n",
    "    System.out.println(\"integer5 != integer6\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们普遍认为上面的两个判断的结果都是false。虽然比较的值是相等的，但是由于比较的是对象，而对象的引用不一样，所以会认为两个if判断都是false的。\n",
    "\n",
    "在Java中，**==比较的是对象应用，而equals比较的是值**。\n",
    "\n",
    "所以，在这个例子中，不同的对象有不同的引用，所以在进行比较的时候都将返回false。奇怪的是，这里两个类似的if条件判断返回不同的布尔值。\n",
    "\n",
    "**原因就和Integer中的缓存机制有关。**在Java 5中，在Integer的操作上引入了一个新功能来节省内存和提高性能。**整型对象通过使用相同的对象引用实现了缓存和重用。**\n",
    "```\n",
    "适用于整数值区间-128 至 +127。\n",
    "只适用于自动装箱。使用构造函数创建对象不适用。\n",
    "```\n",
    "当需要进行自动装箱时，`如果数字在-128至127之间时，会直接使用缓存中的对象，而不是重新创建一个对象。`\n",
    "\n",
    "因为这个范围的数字是最被广泛使用的。 在程序中，第一次使用Integer的时候也需要一定的额外时间来初始化这个缓存。\n",
    "\n",
    "在Boxing Conversion部分的Java语言规范(JLS)规定如下：  \n",
    "变量p的值是\n",
    "```\n",
    "-128至127之间的整数(§3.10.1)\n",
    "true 和 false的布尔值 (§3.10.3)\n",
    "‘\\u0000’至 ‘\\u007f’之间的字符(§3.10.4)\n",
    "```\n",
    "范围内的时，将p包装成a和b两个对象时，可以直接使用a==b判断a和b的值是否相等。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 补充：Java中整型的缓存机制"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Java中Integer的缓存实现\n",
    "在Java 5中，在Integer的操作上引入了一个新功能来节省内存和提高性能。整型对象通过使用相同的对象引用实现了缓存和重用。\n",
    "```\n",
    "适用于整数值区间-128 至 +127。\n",
    "只适用于自动装箱。使用构造函数创建对象不适用。\n",
    "```\n",
    "Java的编译器把基本数据类型自动转换成封装类对象的过程叫做自动装箱，相当于使用valueOf方法："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [],
   "source": [
    "Integer a = 10; //this is autoboxing\n",
    "Integer b = Integer.valueOf(10); //under the hood"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "现在我们知道了这种机制在源码中哪里使用了，那么接下来我们就看看JDK中的valueOf方法。下面是JDK 1.8.0 build 25的实现："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [],
   "source": [
    "/**\n",
    " * Returns an {@code Integer} instance representing the specified\n",
    " * {@code int} value.  If a new {@code Integer} instance is not\n",
    " * required, this method should generally be used in preference to\n",
    " * the constructor {@link #Integer(int)}, as this method is likely\n",
    " * to yield significantly better space and time performance by\n",
    " * caching frequently requested values.\n",
    " *\n",
    " * This method will always cache values in the range -128 to 127,\n",
    " * inclusive, and may cache other values outside of this range.\n",
    " *\n",
    " * @param  i an {@code int} value.\n",
    " * @return an {@code Integer} instance representing {@code i}.\n",
    " * @since  1.5\n",
    " */\n",
    "public static Integer valueOf(int i) {\n",
    "    if (i >= IntegerCache.low && i <= IntegerCache.high)\n",
    "        return IntegerCache.cache[i + (-IntegerCache.low)];\n",
    "    return new Integer(i);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在创建对象之前先从IntegerCache.cache中寻找。如果没找到才使用new新建对象。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### IntegerCache 类\n",
    "IntegerCache是Integer类中定义的一个private static的内部类。接下来看看他的定义。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "ename": "CompilationException",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[1m\u001b[30m|   \u001b[1m\u001b[30m            \u001b[0m\u001b[1m\u001b[30m\u001b[41msun.misc.VM\u001b[0m\u001b[1m\u001b[30m.getSavedProperty(\"java.lang.Integer.IntegerCache.high\");\u001b[0m",
      "\u001b[1m\u001b[31mcannot find symbol\u001b[0m",
      "\u001b[1m\u001b[31m  symbol:   class VM\u001b[0m",
      "",
      "\u001b[1m\u001b[30m|   \u001b[1m\u001b[30m                int i = \u001b[0m\u001b[1m\u001b[30m\u001b[41mparseInt\u001b[0m\u001b[1m\u001b[30m(integerCacheHighPropValue);\u001b[0m",
      "\u001b[1m\u001b[31mcannot find symbol\u001b[0m",
      "\u001b[1m\u001b[31m  symbol:   method parseInt(java.lang.String)\u001b[0m",
      "",
      "\u001b[1m\u001b[30m|   \u001b[1m\u001b[30m\u001b[0m\u001b[1m\u001b[30m\u001b[41mprivate static\u001b[0m\u001b[1m\u001b[30m class IntegerCache {\u001b[0m",
      "\u001b[1m\u001b[31mModifier 'static' not permitted in top-level declarations, ignored\u001b[0m",
      ""
     ]
    }
   ],
   "source": [
    "/**\n",
    " * Cache to support the object identity semantics of autoboxing for values between\n",
    " * -128 and 127 (inclusive) as required by JLS.\n",
    " *\n",
    " * The cache is initialized on first usage.  The size of the cache\n",
    " * may be controlled by the {@code -XX:AutoBoxCacheMax=} option.\n",
    " * During VM initialization, java.lang.Integer.IntegerCache.high property\n",
    " * may be set and saved in the private system properties in the\n",
    " * sun.misc.VM class.\n",
    " */\n",
    "\n",
    "private static class IntegerCache {\n",
    "    static final int low = -128;\n",
    "    static final int high;\n",
    "    static final Integer cache[];\n",
    "\n",
    "    static {\n",
    "        // high value may be configured by property\n",
    "        int h = 127;\n",
    "        String integerCacheHighPropValue =\n",
    "            sun.misc.VM.getSavedProperty(\"java.lang.Integer.IntegerCache.high\");\n",
    "        if (integerCacheHighPropValue != null) {\n",
    "            try {\n",
    "                int i = parseInt(integerCacheHighPropValue);\n",
    "                i = Math.max(i, 127);\n",
    "                // Maximum array size is Integer.MAX_VALUE\n",
    "                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);\n",
    "            } catch( NumberFormatException nfe) {\n",
    "                // If the property cannot be parsed into an int, ignore it.\n",
    "            }\n",
    "        }\n",
    "        high = h;\n",
    "\n",
    "        cache = new Integer[(high - low) + 1];\n",
    "        int j = low;\n",
    "        for(int k = 0; k < cache.length; k++)\n",
    "            cache[k] = new Integer(j++);\n",
    "\n",
    "        // range [-128, 127] must be interned (JLS7 5.1.7)\n",
    "        assert IntegerCache.high >= 127;\n",
    "    }\n",
    "\n",
    "    private IntegerCache() {}\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "其中的javadoc详细的说明了缓存支持-128到127之间的自动装箱过程。最大值127可以通过-XX:AutoBoxCacheMax=size修改。 缓存通过一个for循环实现。从低到高并创建尽可能多的整数并存储在一个整数数组中。这个缓存会在Integer类第一次被使用的时候被初始化出来。以后，就可以使用缓存中包含的实例对象，而不是创建一个新的实例(在自动装箱的情况下)。\n",
    "\n",
    "实际上这个功能在Java 5中引入的时候,范围是固定的-128 至 +127。后来在Java 6中，可以通过java.lang.Integer.IntegerCache.high设置最大值。这使我们可以根据应用程序的实际情况灵活地调整来提高性能。到底是什么原因选择这个-128到127范围呢？因为这个范围的数字是最被广泛使用的。 在程序中，第一次使用Integer的时候也需要一定的额外时间来初始化这个缓存。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Java语言规范中的缓存行为\n",
    "在Boxing Conversion部分的Java语言规范(JLS)规定如下：  \n",
    "变量p的值是\n",
    "```\n",
    "-128至127之间的整数(§3.10.1)\n",
    "true 和 false的布尔值 (§3.10.3)\n",
    "‘\\u0000’至 ‘\\u007f’之间的字符(§3.10.4)\n",
    "```\n",
    "范围内的时，将p包装成a和b两个对象时，可以直接使用a==b判断a和b的值是否相等。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 其他缓存的对象\n",
    "这种缓存行为不仅适用于Integer对象。针对所有的整数类型的类都有类似的缓存机制。\n",
    "- ByteCache用于缓存Byte对象\n",
    "- ShortCache用于缓存Short对象\n",
    "- LongCache用于缓存Long对象\n",
    "- CharacterCache用于缓存Character对象\n",
    "\n",
    "Byte, Short, Long有固定范围: -128 到 127。对于Character, 范围是 0 到 127。除了Integer以外，范围都不能改变。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 自动拆装箱带来的问题\n",
    "当然，自动拆装箱是一个很好的功能，大大节省了开发人员的精力，不再需要关心到底什么时候需要拆装箱。但是，他也会引入一些问题。\n",
    "1. 包装对象的数值比较，不能简单的使用==，虽然-128到127之间的数字可以，但是这个范围之外还是需要使用equals比较。\n",
    "2. 前面提到，有些场景会进行自动拆装箱，同时也说过，由于自动拆箱，如果包装类对象为null，那么自动拆箱时就有可能抛出NPE。\n",
    "3. 如果一个for循环中有大量拆装箱操作，会浪费很多资源。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Java",
   "language": "java",
   "name": "java"
  },
  "language_info": {
   "codemirror_mode": "java",
   "file_extension": ".jshell",
   "mimetype": "text/x-java-source",
   "name": "Java",
   "pygments_lexer": "java",
   "version": "11.0.8+10-post-Ubuntu-0ubuntu120.04"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "302.4px"
   },
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
